package core.proto;

import java.awt.Component;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import core.util.logging.UserLogWriter;
import core.util.logging.constants.Action;
import core.util.logging.constants.Location;


class FileTransferHandler extends TransferHandler {
    DataFlavor nodesFlavor; //content type of DnD object  
    DataFlavor[] flavors = new DataFlavor[1];
    static boolean isFileExist = false;
    DefaultMutableTreeNode dragNode = null;
    
	public FileTransferHandler() {  
		try {  
			String mimeType = DataFlavor.javaJVMLocalObjectMimeType + ";class=\"" + 
				javax.swing.tree.DefaultMutableTreeNode[].class.getName() + "\"";  
			nodesFlavor = new DataFlavor(mimeType);  
			flavors[0] = nodesFlavor;  
		} catch(ClassNotFoundException e) {  
			System.out.println("ClassNotFound: " + e.getMessage());  
		}  
	}  
   
	public int getSourceActions(JComponent c) {
		return TransferHandler.COPY;
	}

	
	public Transferable createTransferable(JComponent comp) {
		System.out.println("createTransferable");
	    
		if (comp instanceof JTree) {
			
			JTree tree = (JTree) comp;
			TreePath[] paths = tree.getSelectionPaths();  
			if(paths != null) {  
				// Get the node for transfer and save into database in exportDone after a sucessful drop 
				DefaultMutableTreeNode node =  (DefaultMutableTreeNode)paths[0].getLastPathComponent(); 
				dragNode = node;
				CaseNode caseNode = (CaseNode) ((IconData) node.getUserObject()).getObject();
				UserLogWriter.log(caseNode.getName(), Location.Directory, Action.DRAGSTART);
				return new NodeTransferable(node);
			}  
			
		} 
			
		return null;
	}

	
	protected void exportDone(JComponent comp, Transferable t, int action) {  
		//System.out.println("exportDone");
    }
	
	public boolean canImport(TransferHandler.TransferSupport support) {
		Component comp = support.getComponent();
		DataFlavor flavor[] = support.getTransferable().getTransferDataFlavors();
		
		// check whether the comp allow dropping
		if (!(comp instanceof JLabel) && 
			!(comp instanceof JEditorPane) &&
			!(comp instanceof JTree)) {
			System.out.println("can not import");	
			return false;
		}
		// check whether the dragged node is a directory; if it's a directory, then could not be dropped
		try {
			DefaultMutableTreeNode node = (DefaultMutableTreeNode)support.getTransferable().getTransferData(flavor[0]);
			if (!node.isLeaf()) // it's a directory node
				return false;
		} catch (UnsupportedFlavorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// check flavors
		for (int i = 0, n = flavor.length; i < n; i++) {
			for (int j = 0, m = flavors.length; j < m; j++) {
				if (flavor[i].equals(flavors[j])) {
					return true;
				}
			}
		}
		return false;
	}

	
	public boolean importData(JComponent comp, Transferable t) {
		System.out.println("importData");
		// check whether the comp allow dropping
		if (!(comp instanceof JLabel) && 
			!(comp instanceof JEditorPane)) {
			System.out.println("can not import data");	
			return false;
		}
		
		// get the dragged node
		DefaultMutableTreeNode node = null;
		try {
			node = (DefaultMutableTreeNode)t.getTransferData(nodesFlavor);
		} catch (UnsupportedFlavorException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return false;
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return false;
		}
		
		// the following process for save file
		if (comp instanceof JLabel) {
			if (!node.isLeaf()) // it's a directory
				return false;
			
			try {
				MotionCanvas canvas = (MotionCanvas) comp;
				Point point = comp.getMousePosition();
		    	// get the dragged node and add the node to motion canvas
		        canvas.addDroppedNode(point.x, point.y, node);
		
		        // start motion
//				System.out.println("show motion ...");
//		        Thread motion = new MotionThread(canvas);
//		        motion.start();
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		// the following process for document
		} else if (comp instanceof JEditorPane) {
			System.out.println("do document process here");
			
			JEditorPane panel = (JEditorPane) comp;
			
	        IconData data = (IconData) node.getUserObject();
	        CaseNode caseNode = (CaseNode) data.getObject();
	        String filepath = caseNode.getAbsolutePath();
	        StringBuffer fileData = new StringBuffer(1000);
	        BufferedReader reader;
			try {
				reader = new BufferedReader(new FileReader(filepath));
		        char[] buf = new char[1024];
		        int numRead=0;
				while((numRead=reader.read(buf)) != -1){
				    String readData = String.valueOf(buf, 0, numRead);
				    fileData.append(readData);
				    buf = new char[1024];
				}
		        reader.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        panel.setText(fileData.toString());
		}
		return false;
	}
	
    
    
	public class NodeTransferable implements Transferable {  
		DefaultMutableTreeNode node;  
 
		public NodeTransferable(DefaultMutableTreeNode node) {  
			this.node = node;  
		}  
 
		public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {  
			if(!isDataFlavorSupported(flavor))  
				throw new UnsupportedFlavorException(flavor);  
			return node;  
		}  
 
		public DataFlavor[] getTransferDataFlavors() {  
			return flavors;  
		}  
 
		public boolean isDataFlavorSupported(DataFlavor flavor) {  
			return nodesFlavor.equals(flavor);  
		}  
	}  
}